﻿using System;
using System.IO;
using System.Diagnostics;
using System.Collections.Generic;

//svnkit imports
using org.tmatesoft.svn.core;
using org.tmatesoft.svn.core.wc;

namespace Subsync.Core.Subversion
{
    class SVNStatus : CommandBase
    {
        // Initialise variables with default settings.
        // public long rev_no;
        public java.io.File local_path;
        public string str_path;
        //public SVNRevision revision = SVNRevision.HEAD;
        //public SVNDepth depth = SVNDepth.INFINITY;
        public bool remote = true;
        //public bool report_all = true;
        //public bool include_ignored = true;
        public bool collect_parent_externals = true;
        //public java.util.ArrayList changeList;
        public List<SVNStatusInfo> statusInfo = new List<SVNStatusInfo>();

        // Minimal constructor.
        public SVNStatus(string path)
        {
            Debug.WriteLine("SVN Status minimal Constructor with defaults");
            this.setupStatus(path);
        }

        // Full constructor.
        public SVNStatus(string path, bool remote, bool collect_parent_ext)
        {
            Debug.WriteLine("SVN Status full Constructor");
            this.local_path = new java.io.File(path);
            this.str_path = path;
            //this.revision = rev;
            //this.depth = depth;
            this.remote = remote;
            //this.report_all = rep_all;
            //this.include_ignored = inc_ignored;
            this.collect_parent_externals = collect_parent_ext;

            this.Execute();
        }

        void setupStatus(string path)
        {
            this.local_path = new java.io.File(path);
            this.str_path = path;
        }

        public override void Execute()
        {
            Debug.WriteLine("SVN Status Execution");
            
            //library setup
            Tools.setupLibrary();

            //load up the clients
            SVNClientManager cm = SVNClientManager.newInstance();
            SVNStatusClient sc = cm.getStatusClient();

            StatusHandler handler = new StatusHandler(remote);
            //changeList = new java.util.ArrayList();

            try
            {
                processFolder(str_path, statusInfo, sc, handler);
            }
            catch (SVNException e)
            {
                throw new SVNExecuteException(e.getMessage());
            }
        }

        private void processFolder(string folder, 
            List<SVNStatusInfo> theList, SVNStatusClient sc, StatusHandler h)
        {
            //If folder contains file, add into list.
            foreach (string file in Directory.GetFiles(folder))
            {
                java.io.File jfile = new java.io.File(file);
                theList.Add(h.handleStatus(sc.doStatus(jfile, remote, collect_parent_externals)));
            }
            //If folder contains another sub-folder, call function recursively.
            foreach (string dir in Directory.GetDirectories(folder))
            {
                java.io.File jfile = new java.io.File(dir);
                theList.Add(h.handleStatus(sc.doStatus(jfile, remote, collect_parent_externals)));
                processFolder(dir, theList, sc, h);
            }
        }

        public override Dictionary<string, List<object>> getTokens ()
		{
			Dictionary<string, List<object>> ret = new Dictionary<string, List<object>> ();
			ret.Add("Status",new List<object>() {"st","status"});
			return ret;
		}
		
		public override List<KeyValuePair<string,initPointer>> getInitPointers() {
			List<KeyValuePair<string,initPointer>> ret = new List<KeyValuePair<string,initPointer>>();
			ret.Add(new KeyValuePair<string,initPointer>("Status",new initPointer(this.handleCLI)));
			return ret;
		}
		
		public void handleCLI(Dictionary<string,List<object>> tokens) {
			if (tokens["Status"].Count == 0) {
				Console.WriteLine("Not enough arguments: Status requires at least 1 argument (path)");
				return;
			}
			string path = (string) tokens["Status"][0];
            this.setupStatus(path);
            this.Execute();
        }

        public SVNStatus() {}
    }
}
